﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////


#include "GnufLineStyleParameterDisplayV2.h"
#include "GnufParameterDisplayCustomFactory.h"
#include "GcmpBuiltInParameterDefinitions.h"
#include "GnufInfo.h"
#include "GnufList.h"
#include "GnufNameValuePairs.h"
#include "IDrawingLine.h"
#include "IElement.h"
#include "IElementBasicInformation.h"
#include "IElementParameters.h"
#include "IFamilyLineStyleManager.h"
#include "IGraphicsStyle.h"
#include "IModelLine.h"
#include "IParameterDefinitionLibrary.h"
#include "IParameterValueElementId.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

using namespace gcmp;
using namespace gfam;

gfam::LineStyleParameterDisplayV2::LineStyleParameterDisplayV2()
{
}

gnuf::Item * gfam::LineStyleParameterDisplayV2::OnDisplay(gnuf::NameValuePairBlock * pNameValuePairBlock, gcmp::IElement * pElement, int parameterId)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pNameValuePairBlock, L"pNameValuePairBlock为空", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pElement, L"pElement为空", L"paramodel", L"2024-02-20");

    IDocument* pDoc = pElement->GetDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"pDoc为空", L"paramodel", L"2024-02-20");

    const IElementParameters* params = pElement->GetElementParameters();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(params, L"params为空", L"paramodel", L"2024-02-20");
    auto param = params->GetParameterById(parameterId);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(param, L"param为空", L"paramodel", L"2024-02-20");
    const IParameterValueStorage* storage = param->GetParameterValueStorage();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(storage, L"storage为空", L"paramodel", L"2024-02-20");
    const IFamilyLineStyleManager* lineStyleMgr = IFamilyLineStyleManager::Get(pDoc);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(lineStyleMgr, L"lineStyleMgr为空", L"paramodel", L"2024-02-20");

    gnuf::List* list = pNameValuePairBlock->addItem<gnuf::List>(gnuf::Info(param->GetName()));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(list, L"list为空", L"paramodel", L"2024-02-20");

    int currentIndex = 0;
    bool curIndexDetermined = false;
    int solidThinIndex = 0;
    for (int i = 0; i < lineStyleMgr->GetBuiltinLineStyleCount(); i++)
    {
        auto lineStyle = lineStyleMgr->GetBuiltinLineStyle(i);
        DBG_WARN_AND_CONTINUE_UNLESS(lineStyle && lineStyle->GetBasicInformation(), L"lineStyle->GetBasicInformation()为空", L"paramodel", L"2024-02-20");
        list->AddItem(NEW_AS_OWNER_PTR(gnuf::Info, lineStyle->GetBasicInformation()->GetName()));
        if (!curIndexDetermined && param->GetValueAsElementId() == lineStyle->GetElementId())
        {
            currentIndex = i;
            curIndexDetermined = true;
        }
        if (lineStyle->GetBasicInformation()->GetName() == L"实线_细")
        {
            solidThinIndex = i;
        }
    }

    for (int i = 0; i <lineStyleMgr->GetUserLineStyleCount(); i++)
    {
        auto lineStyle = lineStyleMgr->GetUserLineStyle(i);
        DBG_WARN_AND_CONTINUE_UNLESS(lineStyle && lineStyle->GetBasicInformation(), L"lineStyle->GetBasicInformation()为空", L"paramodel", L"2024-02-20");
        list->AddItem(NEW_AS_OWNER_PTR(gnuf::Info, lineStyle->GetBasicInformation()->GetName()));
        if (!curIndexDetermined && param->GetValueAsElementId() == lineStyle->GetElementId())
        {
            currentIndex = lineStyleMgr->GetBuiltinLineStyleCount() + i;
            curIndexDetermined = true;
        }
    }

    if (!curIndexDetermined)
    {
        currentIndex = solidThinIndex; // 实线_细(3)
    }
    list->SetSelectedIndex(currentIndex);
    return list;
}

gnuf::Item * gfam::LineStyleParameterDisplayV2::OnDisplay(gnuf::NameValuePairBlock * pNameValuePairBlock, const std::vector<gcmp::IElement*>& elements, int parameterId)
{
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pNameValuePairBlock, L"pNameValuePairBlock为空", L"paramodel", L"2024-02-20");
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(elements.size() > 0, L"elements为空", L"paramodel", L"2024-02-20");

    IDocument* pDoc = elements[0]->GetDocument();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDoc, L"pDoc为空", L"paramodel", L"2024-02-20");

    const IElementParameters* params = elements[0]->GetElementParameters();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(params, L"params为空", L"paramodel", L"2024-02-20");
    auto param = params->GetParameterById(parameterId);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(param, L"param为空", L"paramodel", L"2024-02-20");
    gnuf::List* list = pNameValuePairBlock->addItem<gnuf::List>(gnuf::Info(param->GetName()));
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(list, L"list为空", L"paramodel", L"2024-02-20");
    list->AddItem(NEW_AS_OWNER_PTR(gnuf::Info, L"*多种样式*"));

    const IFamilyLineStyleManager* lineStyleMgr = IFamilyLineStyleManager::Get(pDoc);
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(lineStyleMgr, L"lineStyleMgr为空", L"paramodel", L"2024-02-20");

    for (int i = 0; i < lineStyleMgr->GetBuiltinLineStyleCount(); i++)
    {
        auto lineStyle = lineStyleMgr->GetBuiltinLineStyle(i);
        DBG_WARN_AND_CONTINUE_UNLESS(lineStyle && lineStyle->GetBasicInformation(), L"lineStyle->GetBasicInformation()为空", L"paramodel", L"2024-02-20");
        list->AddItem(NEW_AS_OWNER_PTR(gnuf::Info, lineStyle->GetBasicInformation()->GetName()));
    }

    for (int i = 0; i < lineStyleMgr->GetUserLineStyleCount(); i++)
    {
        auto lineStyle = lineStyleMgr->GetUserLineStyle(i);
        DBG_WARN_AND_CONTINUE_UNLESS(lineStyle && lineStyle->GetBasicInformation(), L"lineStyle->GetBasicInformation()为空", L"paramodel", L"2024-02-20");
        list->AddItem(NEW_AS_OWNER_PTR(gnuf::Info, lineStyle->GetBasicInformation()->GetName()));
    }

    list->SetSelectedIndex(0);
    return list;
}

gcmp::OwnerPtr<gcmp::IParameterValueStorage> gfam::LineStyleParameterDisplayV2::GetValue(gcmp::IDocument* pDoc, const std::vector<gcmp::ElementId>& elements, const gnuf::Item* pItem) const
{
    const gnuf::List* list = dynamic_cast<const gnuf::List*>(pItem);
    if (list)
    {
        int currentIndex = list->GetSelectedIndex();

        // 第一个为“*多种样式*”时，需要排除掉
        gnuf::List *pList = const_cast<gnuf::List*>(list);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pList, L"pList为空", L"paramodel", L"2024-02-20");
        if (!pList->GetItemInfos().empty())
        {
            const gcmp::OwnerPtr<gnuf::Info> &opInfo = pList->GetItemInfos().at(0);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opInfo, L"opInfo为空", L"paramodel", L"2024-02-20");
            if (opInfo->caption() == L"*多种样式*")
            {
                --currentIndex;
            }
        }

        const IFamilyLineStyleManager *lineStyleMgr = IFamilyLineStyleManager::Get(pDoc);
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(lineStyleMgr, L"lineStyleMgr为空", L"paramodel", L"2024-02-20");
        if (currentIndex >= 0 && currentIndex < lineStyleMgr->GetBuiltinLineStyleCount())
        {
            ElementId id = lineStyleMgr->GetBuiltinLineStyleId(currentIndex);
            return IParameterValueElementId::Create(id);
        }
        else if (currentIndex >= lineStyleMgr->GetBuiltinLineStyleCount() && currentIndex < lineStyleMgr->GetBuiltinLineStyleCount() + lineStyleMgr->GetUserLineStyleCount())
        {
            ElementId id = lineStyleMgr->GetUserLineStyleId(currentIndex -lineStyleMgr->GetBuiltinLineStyleCount());
            return IParameterValueElementId::Create(id);
        }
        else
        {
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(lineStyleMgr->GetBuiltinLineStyle(0), L"BuiltinLineStyle(0)为空", L"paramodel", L"2024-02-20");
            ElementId id = lineStyleMgr->GetBuiltinLineStyle(0)->GetElementId();
            return IParameterValueElementId::Create(id);
        }
    }

    return gcmp::OwnerPtr<gcmp::IParameterValueStorage>();
}

GnufParameterDisplayCustomCreator s_lineStyleParameterDisplayCreator(
    PARAMETER_UID(FamilyLineStyleBuiltInParameter), NEW_AS_OWNER_PTR(LineStyleParameterDisplayV2));